#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <math.h>

#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

#define INT32 int
#define NSLOOKUP_RESULT_FILE "./result_nslookup.txt"

INT32 get_pid_by_index_from_proc(int index)
{
	DIR *dir = NULL;
	struct dirent * ptr;
	int proc_num = 0;
	int pid = -1;

	dir = opendir("/proc/");
	if(!dir)
		return pid;

	while((ptr = readdir(dir)) != NULL){
		if(atoi(ptr->d_name) <= 0)
			continue;

		proc_num++;
		if(index == proc_num){
			pid = atoi(ptr->d_name);
			break;
		}
	}
	closedir(dir);
	
	if(pid < 0)
		return proc_num;

	return pid;
}

void get_process_info_by_pid(int pid, char *key, char *value)
{
	FILE *fp = NULL;
	char line[2048] = {0};
	char col[18][64];
	char stat_filename[64] = {0};
	char *ptr = NULL, *prt1 = NULL;
	if (strcmp(key, "Command") == 0 || strcmp(key, "Priority") == 0 || strcmp(key, "CPUTime") == 0){
		sprintf(stat_filename, "/proc/%d/stat", pid);
		if ((fp = fopen(stat_filename, "r")) != NULL) {
			fgets(line, sizeof(line), fp);
			sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s ",
				col[0], col[1], col[2], col[3], col[4], col[5], col[6],
				col[7], col[8], col[9], col[10], col[11], col[12], 
				col[13],col[14], col[15], col[16], col[17]);
			//command
			if (strcmp(key, "Command") == 0){
				ptr=strtok(col[1]+1,")");
				if (ptr != NULL)
					strcpy(value, ptr);
				else
					strcpy(value, col[1]);
			}
			//priority
			if (strcmp(key, "Priority") == 0)
				strcpy(value, col[17]);
			//cputime
			if (strcmp(key, "CPUTime") == 0){
				unsigned int HZ = sysconf(_SC_CLK_TCK);
				sprintf(value, "%u", 1000/HZ * (strtoul(col[13], NULL, 0) + strtoul(col[14], NULL, 0)));
			}
			fclose(fp);
		}
	}

	if (strcmp(key, "State") == 0 || strcmp(key, "Size") == 0){
		sprintf(stat_filename, "cat /proc/%d/status", pid);
		if ((fp = popen(stat_filename, "r")) != NULL) {
			memset(line, 0, sizeof(line));
			while (fgets(line, sizeof(line), fp)) {
				//State
				if (strcmp(key, "State") == 0){
					if ((ptr = strstr(line, "State:")) != NULL) {
						if ((prt1 = strchr(ptr + sizeof("State:"), '\n')) != NULL)
							*prt1 = '\0';
						strcpy(value, ptr + sizeof("State:"));
					}
				}
				//Size
				if (strcmp(key, "Size") == 0){
					if (strstr(line, "VmSize:") != NULL) {
						char size[2][64];
						sscanf(line, "%s %s ", size[0], size[1]);
						strcpy(value, size[1]);
					}
				}
				memset(line, 0, sizeof(line));
			}
			pclose(fp);
		}
	}
}

int main(int argc, char *argv[])
{
	int index = 0;
	int pid = 0;
	int proc_num = 0;
	char cmd[256] = {0};
	char priority[256] = {0};
	char cputime[256] = {0};
	char state[256] = {0};
	char size[256] = {0};

	proc_num = get_pid_by_index_from_proc(-1);
	printf("proc_num = %d\n", proc_num);
	for( index = 1; index <= proc_num; index++){
		pid = get_pid_by_index_from_proc(index);
		printf("index=[%4d] pid=[%6d] ", index, pid);
		get_process_info_by_pid(pid, "Command", cmd);
		get_process_info_by_pid(pid, "Priority", priority);
		get_process_info_by_pid(pid, "CPUTime", cputime);
		get_process_info_by_pid(pid, "State", state);
		get_process_info_by_pid(pid, "Size", size);
		printf("	cmd=[%20s], priority=[%5s], cputime=[%5s], state=[%15s], size={%10s]\n",
			cmd, priority, cputime, state, size);
	}

	return 0;
}
